lib.modules: refactor into composable layers with flag ordering#147
Merged
lib.modules: refactor into composable layers with flag ordering#147
Conversation
The wrapper and systemd modules share a common command specification (package, args, env, flags, hooks). Extract these shared options into a new command.nix base module, making wrapper one output format alongside systemd rather than the core abstraction. - Create lib/modules/command.nix with shared options (flags, args, env, exePath, binName, extraPackages, preHook, postHook) - Slim wrapper.nix to only wrapper-specific options (filesToPatch, filesToExclude, patchHook) and move output to outputs.wrapper - Add backward-compat alias for config.wrapper
Extract flags/flagSeparator into a new flags.nix module, separate from
command.nix. Flags now support per-flag ordering via { value, order }
submodules with coercion so the shorthand (flags."--foo" = "bar") still
works. Reading config.flags returns clean values (apply strips order).
An internal _orderedFlags option preserves order info, and args are
generated using mkOrder per-flag so listOf merge handles positioning.
Instead of hardcoding "$@" in the wrapper template, inject it into the args list at order 1001 (just after the default flag order of 1000). This makes passthrough argument positioning controllable via the ordering system — flags with order > 1001 appear after "$@". The wrapper module passes a custom wrapper function to wrapPackage that omits the hardcoded "$@" since it's now part of args. Add flags-order check verifying: --early (500) < --greeting (1000) < "$@" (1001) < --late (1500).
The " " default was confusing: it didn't join with a space but produced separate argv entries. Change the default to null which clearly means "separate argv entries", while " " now actually joins with a space (single arg). This makes the semantics consistent with "=". null → ["--flag" "value"] (separate args, default) "=" → ["--flag=value"] (joined) " " → ["--flag value"] (joined with space)
Instead of hardcoding "$@" in the wrapper template, include it in the default args list. The template no longer appends "$@" on its own. This means passing explicit args to wrapPackage gives full control over whether "$@" is included. The default args (from flags) still append "$@" for backward compatibility. Removes the custom wrapper function override from wrapper.nix since wrapPackage's template no longer conflicts with the module's "$@" injection. Add CHANGELOG documenting breaking changes.
zimward
reviewed
Apr 7, 2026
Collaborator
zimward
left a comment
There was a problem hiding this comment.
generally looks quite good, especially pulling the options out into their own modules
4aa05ee to
1255994
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refactor lib/modules into composable layers and add priority-based flag ordering.
commandbase module fromwrapper.nixwith shared command spec (args, env, hooks, exePath) used by both wrapper and systemd outputsflagsmodule with per-flag ordering via{ value, order }submodules (shorthand still works, reading returns clean values)"$@"from wrapper template into default args inwrapPackage, and inject at order 1001 in wrapper.nix so passthrough positioning is controllableflagSeparatordefault from" "tonullfor correct semanticsModule hierarchy:
Flag ordering example:
flagSeparator semantics: